package juc.test_inc;

import juc.aqs.MyLock;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestInc {
    private static int num = 0;

    private static Object lock = new Object();

    private static Lock reentrantLock = new ReentrantLock();

    private static Lock myLock = new MyLock();

    public static void main(String[] args) throws InterruptedException {
        int count = 10;// result = 10000
        CountDownLatch countDownLatch = new CountDownLatch(count);
        for (int i = 0; i < count; i++) {
            // 1.单线程
            //handle(countDownLatch);
            // 2.多线程->出现线程安全问题
            //new Thread(()->{handle(countDownLatch);}).start();

            // 3.synchronized锁
            // synchronizedLock(countDownLatch);

            // 4.ReentrantLock锁
            //reentrantLock(countDownLatch);

            // 5.MyLock锁
            myLock(countDownLatch);

        }
        countDownLatch.await();
        System.out.println(num);
    }

    private static void myLock(CountDownLatch countDownLatch) {
        new Thread(()->{
            myLock.lock();
            try {
                handle(countDownLatch);
            } finally {
                myLock.unlock();
            }
        }).start();
    }

    private static void synchronizedLock(CountDownLatch countDownLatch) {
        new Thread(()->{
            synchronized (lock) {
                handle(countDownLatch);
            }
        }).start();
    }

    private static void reentrantLock(CountDownLatch countDownLatch) {
        new Thread(()->{
            reentrantLock.lock();
            try {
                handle(countDownLatch);
            } finally {
                reentrantLock.unlock();
            }
        }).start();
    }

    private static void handle(CountDownLatch c) {
        myLock.lock();
        try {
            for (int j = 0; j < 1000; j++) {
                num++;
            }
        } finally {
            myLock.unlock();
        }
        c.countDown();
    }

}
